﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using Microsoft.Win32;
using System.Windows;
using System.Xml;
using SHomeWorkshop.LunarConcept.Controls;
using SHomeWorkshop.LunarConcept.ModifingManager;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using System.IO;
using System.Windows.Media;
using SHomeWorkshop.LunarConcept.Converters;

namespace SHomeWorkshop.LunarConcept.Commands
{
    /// <summary>
    /// 创建时间：2012年1月4日
    /// 创建者：  杨震宇
    /// 
    /// 主要用途：按tiff格式导出较清晰的切分图集（每页导出为一张tiff格式的图片，需要指定目标文件夹）。
    /// ★★说明：关于自定义命令的实现，可参考“NewDocument”类的备注。
    /// </summary>
    public static class OutportSplitTIFFImagesCommand
    {
        #region 构造方法=====================================================================================================

        /// <summary>
        /// ★②，修改静态构造方法名。
        /// </summary>
        static OutportSplitTIFFImagesCommand()//类型构造器
        {
            //★③，修改两个字符串参数名。★④以及第三个参数的类型名。
            routedUICmd = new RoutedUICommand(
                "OutportSplitTIFFImagesCommand",
                "OutportSplitTIFFImagesCommand",
                typeof(OutportSplitTIFFImagesCommand),//创建RoutedUICommand对象
                null);

            //如果需要挂接快捷键，请参考下面这段代码：
            //routedUICmd = new RoutedUICommand(
            //    "OutportSplitTIFFImagesCommand",
            //    "OutportSplitTIFFImagesCommand",
            //    typeof(OutportSplitTIFFImagesCommand),//创建RoutedUICommand对象
            //    new InputGestureCollection() 
            //    { 
            //        //★⑤，修改此处三个参数，以便挂接快捷键。
            //        new KeyGesture(Key.S,ModifierKeys.Control,"Ctrl+S")
            //    });

            cmdBinding.Command = routedUICmd;
            cmdBinding.CanExecute += new CanExecuteRoutedEventHandler(cmdBinding_CanExecute);
            cmdBinding.Executed += new ExecutedRoutedEventHandler(cmdBinding_Executed);
        }

        #endregion

        #region 字段与属性===================================================================================================

        private static CommandBinding cmdBinding = new CommandBinding();
        /// <summary>
        /// 用在主窗口CommandBindings集合中的命令绑定。
        /// 
        /// 它的Command是RoutedUICommand。
        /// ——因此，RoutedUICommand是否可以运行将由CmdBinding的CanExecute事件决定。
        /// ——而且，RoutedUICommand的执行也是通过CmdBinding的Execute事件来进行的。
        /// </summary>
        public static CommandBinding CmdBinding
        {
            get { return cmdBinding; }
        }

        private static RoutedUICommand routedUICmd;
        /// <summary>
        /// [只读静态属性]表示在WPF系统中注册的一个RoutedUICommand。
        /// ——必须和CommandBinding配合才能使用。
        ///     CommandBinding要添加到主窗口的CommandBindings集合中；
        ///     RoutedUICommand则要向WPF系统注册。
        ///     
        /// ★说明：使用静态属性是因为这样在Xaml代码中比较便于绑定。
        /// </summary>
        public static RoutedUICommand RoutedUICmd
        {
            get { return routedUICmd; }
        }

        #endregion

        #region 方法=========================================================================================================

        static void cmdBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            //★⑧，修改此方法的实现。

            //考虑到性能问题，全部取消此判断。反正执行时会判断。
            //if (Globals.MainWindow == null)
            //{
            //    e.CanExecute = false; return;
            //}

            //EditorManager manager = Globals.MainWindow.EditorManager;

            //if (manager == null)
            //{
            //    e.CanExecute = false; return;
            //}

            //if (manager.GetAllPageEditors().Count <= 0)
            //{
            //    e.CanExecute = false; return;
            //}

            e.CanExecute = true; return;
        }

        static void cmdBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            //★⑦，修改此方法的实现。
            LunarMessage.Warning(Execute());
        }

        /// <summary>
        /// [公开静态方法]即使此命令处于禁用状态，也可以通过代码调用此方法来执行特定任务！！！
        /// 
        /// 当被绑定的命令被调用（触发）时，会引发cmdBinding_Executed事件。
        /// 在cmdBinding_Executed事件处理器方法中已添加了调用Execute()方法的代码。
        /// 
        /// ——因此，触发命令，就相当于调用此方法！！！
        /// </summary>
        public static string Execute(string newPaperTypeName = "A4")
        {
            if (Globals.MainWindow == null) return "　　未找到Globals.MainWindow。";

            EditorManager manager = Globals.MainWindow.EditorManager;

            if (manager == null) return "　　未找到页面管理器。";

            List<PageEditor> pages = manager.GetAllPageEditors();
            if (pages.Count <= 0)
            {
                return "　　此文档没有页面可以导出图片文件。";
            }

            if (TextOptions.GetTextFormattingMode(Globals.MainWindow.MainScrollViewer) != TextFormattingMode.Ideal)
            {
                MessageBoxResult msgBoxResult = MessageBox.Show("　　当前文档的显示方式为“锐利”，这适合屏幕显示，" +
                    "而不适合导出图片打印（文字会有锯齿）。\r\n" +
                    "　　您可以使用主界面“视图”功能区“文字渲染”组中两个按钮来在两种文字渲染方式间切换。\r\n\r\n" +
                    "　　真的要继续吗？",
                    Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning);
                if (msgBoxResult != MessageBoxResult.Yes) return string.Empty;
            }
            //导出图像

            double scale = ScaleValueConverter.GetNewScaleValue(Globals.MainWindow.SliderOfScale.Value);

            if (scale < 1)
            {
                MessageBoxResult mbr = MessageBox.Show("　　当前文档的缩放比例小于１，导出的图片文件可能比较模糊。要继续吗？",
                    Globals.AppName, MessageBoxButton.YesNo, MessageBoxImage.Warning);
                if (mbr != MessageBoxResult.Yes) return string.Empty;
            }

            System.Windows.Forms.FolderBrowserDialog fbd = new System.Windows.Forms.FolderBrowserDialog();
            fbd.Description = "请选择一个文件夹来导出图片。\r\n——建议新建一个文件夹";
            System.Windows.Forms.DialogResult r = fbd.ShowDialog();

            if (r != System.Windows.Forms.DialogResult.OK)
            {
                Globals.MainWindow.MainScrollViewer.Focus();
                fbd.Dispose();
                return string.Empty;
            }

            string defFileNamePrefix = fbd.SelectedPath;
            fbd.Dispose();

            if (defFileNamePrefix.EndsWith("\\") == false)
            {
                defFileNamePrefix += "\\";
            }

            System.Windows.Media.Imaging.RenderTargetBitmap rtb;

            for (int i = 0; i < pages.Count; i++)
            {
                PageEditor pe = pages[i];

                TiffBitmapEncoder encoder = new TiffBitmapEncoder();

                int width = 0, height = 0, leftOffset = 0, topOffset = 0;
                rtb = pe.GetRenderTargetBitmap(ref width, ref height, ref leftOffset, ref topOffset, true);
                if (rtb == null)
                {
                    return string.Format("发生意外错误，未能获取ID为{0}PageEditor的图形，无法继续打印！", pe.Id);
                }

                int realWidth = width - leftOffset;
                int realHeight = height - topOffset;

                Int32Rect pieceRect = new Int32Rect(leftOffset, topOffset, realWidth, realHeight);
                var array = new byte[realWidth * realHeight * rtb.Format.BitsPerPixel / 8];//每像素需要32位（4字节）。

                rtb.CopyPixels(pieceRect, array, realWidth * rtb.Format.BitsPerPixel / 8, 0);

                //跨度，每行像素数据的总字节数
                //int stride = rtb.PixelWidth * rtb.Format.BitsPerPixel / 8;
                //stride += 4 - stride % 4; //补上几个字节，使其可以被4整除 

                BitmapSource newBitmapSource = BitmapImage.Create(realWidth, realHeight, 300, 300,
                    PixelFormats.Pbgra32, null, array, realWidth * rtb.Format.BitsPerPixel / 8);

                encoder.Frames.Add(BitmapFrame.Create(newBitmapSource));

                string shortFileName = manager.DefaultShortFileName;
                if (shortFileName == null || shortFileName.Length <= 0)
                {
                    shortFileName = "Lunar_Concept_概念图_";
                }
                else
                {
                    string extensionName = "." + Globals.ExtensionName;
                    if (shortFileName.Contains(extensionName))
                    {
                        shortFileName = shortFileName.Replace(extensionName, string.Empty);
                    }

                    if (shortFileName.EndsWith("_") == false)
                    {
                        shortFileName = shortFileName + "_";
                    }
                }

                using (Stream stm = File.Create(defFileNamePrefix + shortFileName +
                    (i + 1).ToString("D4") + ".tiff"))
                {
                    encoder.Save(stm);
                }
            }

            MessageBox.Show(string.Format("已将文件导出到：{0}", defFileNamePrefix),
                Globals.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
            Globals.MainWindow.MainScrollViewer.Focus();

            return string.Empty;
        }

        #endregion
    }
}
